package com.ruoyi.web.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.business.User;
import com.ruoyi.business.ao.RefundAO;
import com.ruoyi.business.ao.UserAO;
import com.ruoyi.business.ao.UserRegisterAO;
import com.ruoyi.business.bo.AccountBO;
import com.ruoyi.business.bo.RefundResult;
import com.ruoyi.business.qo.AccountQO;
import com.ruoyi.business.qo.UserQO;
import com.ruoyi.business.service.SmsService;
import com.ruoyi.business.service.UserService;
import com.ruoyi.business.vo.AccountDetailVO;
import com.ruoyi.common.common.CodeLimit;
import com.ruoyi.common.common.CommonEnum;
import com.ruoyi.common.common.GlobalValue;
import com.ruoyi.common.common.ResultBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;

/**
 * @title: UserController
 * @copyright: copyright (c) 2021
 * @author: jiangguanjun
 * @date: 2023/2/8 10:20
 * @firstReview:
 * @lastReview:
 * @desc: 用户添加
 */
@Api(value = "UserController", tags = "用户相关")
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SmsService smsService ;
    @Value("${tencent.sms.codeTemplateId}")
    private String codeTemplateId ;


    @Value("${city.path}")
    private String path  ;

    @Value("${vip.price}")
    private Integer vipPrice  ;

    @CrossOrigin
    @PostMapping("/editByAdmin")
    @ApiOperation(value = "管理员修改用户信息 必填字段：id  选填字段：phone，status，buyout")
    public ResultBody editByAdmin(@RequestBody UserAO userAO){

        if(userAO == null || userAO.getId() == null){
            log.error(CommonEnum.USER_UPDATE_PARAM_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.USER_UPDATE_PARAM_ERROR) ;

        }
        User userDB = userService.getById(userAO.getId()) ;
        if(userDB == null){
            log.error(CommonEnum.USER_NOT_EXIST_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.USER_NOT_EXIST_ERROR) ;
        }

        return userService.edit(userAO) ;
    }

    @CrossOrigin
    @PostMapping("/editByUser")
    @ApiOperation(value = "管理员修改用户信息 必填字段：id  选填字段：phone")
    public ResultBody editByUser(@RequestBody UserAO userAO){

        if(userAO == null || userAO.getId() == null){
            log.error(CommonEnum.USER_UPDATE_PARAM_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.USER_UPDATE_PARAM_ERROR) ;

        }
        User userDB = userService.getById(userAO.getId()) ;
        if(userDB == null){
            log.error(CommonEnum.USER_NOT_EXIST_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.USER_NOT_EXIST_ERROR) ;
        }
        UserAO userAOEdit = new UserAO() ;
        userAOEdit.setId(userAO.getId());
        userAOEdit.setPhone(userAO.getPhone());

        return userService.edit(userAO) ;
    }


    @CrossOrigin
    @GetMapping("/myDetail")
    @ApiOperation(value = "获取我的详情")
    public ResultBody<User> myDetail(){

        Long id = SecurityUtils.getUserId() ;

        return userService.detail(id) ;
    }

    @CrossOrigin
    @GetMapping("/myDetailById")
    @ApiOperation(value = "通过id获取详情")
    public ResultBody<User> register(@RequestParam Long id){


        return userService.detail(id) ;
    }
    @CrossOrigin
    @PostMapping("/login")
    @ApiOperation(value = "用户注册、登录")
    public ResultBody register(@RequestBody UserRegisterAO userRegisterAO){

        if(userRegisterAO == null ){
            log.error(CommonEnum.USER_UPDATE_PARAM_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.USER_UPDATE_PARAM_ERROR) ;
        }
        if(userRegisterAO.getSmsCode() == null){
            return ResultBody.error(CommonEnum.USER_UPDATE_PARAM_ERROR) ;
        }


        return userService.register(userRegisterAO) ;
    }

    /**
     *
     * @return
     */
    @ApiOperation(value = "获取验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "phone", dataType = "String")
    })
    @PostMapping("/getSmsCode")
    public ResultBody getSmsCode(@RequestBody JSONObject jsonObject) {
        try {
            String phone = jsonObject.getString("phone") ;

            //校验是否频繁获取
            String delyKey = GlobalValue.getPhoneCodeDely(phone) ;
            if(redisTemplate.hasKey(delyKey)){
                return ResultBody.error("获取验证码频繁，请稍后获取") ;
            }

            // 校验是否大于最大次数限制
            CodeLimit codeLimit = GlobalValue.getSmsLimitCount(phone) ;
            Integer count = 0 ;
            if(redisTemplate.hasKey(codeLimit.getKey())){
                count = (Integer) redisTemplate.opsForValue().get(codeLimit.getKey());
                if(count.intValue()>=codeLimit.getMaxCount()){
                    log.info("超出24小时获取三次的限制");
                    return ResultBody.error("超出24小时获取三次的限制") ;
                }
            }
            // 测试先写死短信验证码
            String smsCode = StringUtils.getRandomStr(6,false,true,false) ;
            String content[] = {smsCode} ;
            /*Boolean success = smsService.sendSms(phone,content,codeTemplateId) ;
            if(!success){
                return ResultBody.error("发送验证码失败") ;
            }*/

            redisTemplate.opsForValue().set(GlobalValue.userCodeRedisKey(phone),smsCode,10000000L, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(delyKey,phone,60L,TimeUnit.SECONDS);
            count+=1 ;
            redisTemplate.opsForValue().set(codeLimit.getKey(),count,codeLimit.getExpire(),TimeUnit.SECONDS);
            return ResultBody.success() ;
        } catch (Exception e) {
            log.error("获取验证码失败：", e);
            return ResultBody.error("获取验证码失败");
        }
    }

    /**
     * 登录
     *
     * @return
     */
   /* @CrossOrigin
    @PostMapping("/login")
    @ApiOperation(value = "用户登录 ")
    public ResultBody<String> login(@RequestBody UserLoginAO userLoginAO) {
        log.info("userLoginAO:{}", userLoginAO);


        String phone = userLoginAO.getPhone() ;
        String code = (String) redisTemplate.opsForValue().get(GlobalValue.userCodeRedisKey(phone));
        if(!code.equals(userLoginAO.getSmsCode())){
            throw new BizException("验证码不正确") ;
         }
        return userService.login(userLoginAO) ;

    }*/

    @CrossOrigin
    @GetMapping("/list")
    @ApiOperation(value = "查询列表  页面：采购-关注会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer"),
            @ApiImplicitParam(name = "nike", value = "昵称", dataType = "String"),
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态 0：正常 1：禁用  禁用状态的用户不推送消息", dataType = "String"),
            @ApiImplicitParam(name = "cId", value = "cId 品类id", dataType = "Integer"),
            @ApiImplicitParam(name = "createStartTime", value = "注册开始时间", dataType = "Long"),
            @ApiImplicitParam(name = "createEndTime", value = "注册结束时间", dataType = "Long"),
            @ApiImplicitParam(name = "openId", value = "用户openId", dataType = "String")
    })
    public ResultBody list(@RequestParam(value = "id" ,required = false) Integer id,
                                  @RequestParam(value = "nike" ,required = false) String nike,
                                  @RequestParam(value = "phone" ,required = false) String phone,
                                  @RequestParam(value = "status" ,required = false) Integer status,
                                  @RequestParam(value = "cId" ,required = false) Integer cId,
                                  @RequestParam(value = "createStartTime" ,required = false) String createStartTime,
                                  @RequestParam(value = "createEndTime" ,required = false) String createEndTime,
                                  @RequestParam(value = "openId" ,required = false) String openId){


        UserQO userQO = new UserQO() ;
        userQO.setcId(cId);
        userQO.setId(id);
        userQO.setNike(nike);
        userQO.setPhone(phone);
        userQO.setStatus(status);
        userQO.setOpenId(openId);
        if(createEndTime != null){
            userQO.setCreateEndDate(createEndTime + " 23:59:59");
        }
        if(createStartTime != null){
            userQO.setCreateStartDate(createStartTime+" 00:00:00");
        }
        return userService.queryByPage(userQO) ;
    }

    @CrossOrigin
    @PostMapping("/tokenCheck")
    @ApiOperation(value = "校验token是否失效")
    public ResultBody tokenCheck(){

        return ResultBody.success() ;
    }

    @CrossOrigin
    @PostMapping("/buyVip")
    @ApiOperation(value = "购买用户购买VIP")
    public ResultBody buyVip(){

        Long userId = SecurityUtils.getUserId() ;

        return userService.buyVip(vipPrice,userId) ;
    }

    @CrossOrigin
    @PostMapping("/buyVipNotify")
    @ApiOperation(value = "购买vip的回调接口，不需要前端调试")
    public JSONObject buyVipNotify(HttpServletRequest requestt) throws Exception {

        return userService.buyVipNotify(requestt) ;
    }

    @CrossOrigin
    @PostMapping("/refundNotify")
    @ApiOperation(value = "退款购买vip的回调，不需要前端调试")
    public JSONObject refundNotify(HttpServletRequest request) throws Exception {

        return userService.refundNotify(request) ;
    }

  /*  @CrossOrigin
    @ApiOperation(value = "用户充值，该接口暂时无法联调，内部支付只能等备案之后才能处理")
    @PostMapping("/refund")
    public ResultBody<RefundResult> refund(@RequestBody RefundAO refundAO){

        return userService.refund(refundAO) ;
    }
*/
    @CrossOrigin
    @PostMapping("/myAccount")
    @ApiOperation(value = "我的账户明细")
    public ResultBody<IPage<AccountDetailVO>> myAccount(@RequestBody AccountQO accountQO) throws ParseException {
        Long userId = SecurityUtils.getUserId() ;

        AccountBO accountBO = new AccountBO() ;
        accountBO.setBusiType(accountQO.getBusiType());
        accountBO.setMoneyHigh(accountQO.getMoneyHigh());
        accountBO.setMoneyLow(accountQO.getMoneyLow());
        if(StringUtils.isNotBlank(accountQO.getStartTime())){
            accountBO.setStartDate(format.parse(accountQO.getStartTime()+" 00:00:00"));
        }
        if(StringUtils.isNotBlank(accountQO.getEndTime())){
            accountBO.setEndDate(format.parse(accountQO.getEndTime()+" 23:59:59"));
        }
        accountBO.setUserId(userId);

        return userService.myAccount(accountBO) ;
    }



}

